package com.hsmpay.yl8583.utils;

import java.nio.ByteBuffer;
import java.security.SecureRandom;
import java.util.Date;
import javax.crypto.SecretKeyFactory;
import javax.crypto.SecretKey;
import javax.crypto.Cipher;
import javax.crypto.spec.DESKeySpec;
import com.hsmpay.utils.NumberUtil;
import com.hsmpay.utils.TimeUtils;
import org.apache.log4j.Logger;
import com.hsmpay.utils.DesUtil;

public class TestDes {
	static Logger log = Logger.getLogger(TestDes.class);
	private final static String DES = "DES";
	private final static String CIPHER_ALGORITHM = "DES/ECB/NoPadding";

	/**
	 * pin加密
	 * 
	 * @param Pan
	 * 			主账号
	 * @param Pin
	 * 			明文密码
	 * @param PinKey
	 * 			明文PIN密钥
	 * @param MasterKey
	 * 			主密钥
	 */
	public static String MakeDesPin(String Pan,String Pin,String PinKey, String MasterKey)
	{
		if (PinKey.length() ==32){
			PinKey=DesUtil.decode3DES(PinKey,MasterKey);
		}else{
			PinKey = DesUtil.decodc(PinKey, MasterKey);
		}
		String DesPin="";
		try{
			Pan=Pan.substring(Pan.length()-13, Pan.length()-1);
			int PanLen=Pan.length();
			for(int i=0;i<16-PanLen;i++)
			{
				Pan="0"+Pan;
			}
			Pin=Int2HexStr(Pin.length())+Pin;
			int PinLen=Pin.length();
			for(int j=0;j<16-PinLen;j++)
			{
				Pin+="F";
			}
			byte[] res=XORContent(hexStringToByte(Pin),hexStringToByte(Pan));
			log.debug("异或数据=["+Pan+"]["+Pin+"]");
			log.debug("异或的结果=["+byte2hex(res)+"]");
			if(PinKey.length()==32)
			{
				log.debug("=====加密开始========");
				log.debug("加密数据=["+byte2hex(res)+"]["+PinKey+"]");
				byte[] res1=DesUtil.compute3DES(getDESKey(PinKey),res);
				DesPin=byte2hex(res1);
				log.debug("加密的结果=["+DesPin+"]");
				log.debug("=====加密结束========");
			}else{
				log.debug("=====加密开始========");
				log.debug("加密数据=["+byte2hex(res)+"]["+PinKey+"]");
				byte[] res1=encodc(res,getDESKey(PinKey));
				DesPin=byte2hex(res1);
				log.debug("加密的结果=["+DesPin+"]");
				log.debug("=====加密结束========");
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
		return DesPin;
	}

	/**
	 * pin解密
	 *
	 * @param Pan
	 * 			主账号
	 * @param Pin
	 * 			明文密码
	 * @param PinKey
	 * 			明文PIN密钥
	 */
	public static String decryptPin(String Pan, String Pin, String PinKey)
	{

		String DesPin="";
		byte[] res;
		try{
			if (PinKey.length() == 32){
				log.debug("=====解密开始=====");
				log.debug("解密数据=[" + Pin + "][" + PinKey + "]");
				res = DesUtil.decode3DES(hexStringToByte(Pin), getDESKey(PinKey));
				log.debug("解密的数据为: " + DesPin);
				log.debug("=====解密结束=====");
			}else{
				log.debug("=====解密开始=====");
				log.debug("解密数据=[" + Pin + "][" + PinKey + "]");
				res = DesUtil.decodc(hexStringToByte(Pin), getDESKey(PinKey));
				log.debug("解密的数据为: " + DesPin);
				log.debug("=====解密结束=====");
			}
			//得到Pan格式
			Pan=Pan.substring(Pan.length()-13, Pan.length()-1);
			int PanLen=Pan.length();
			for(int i=0;i<16-PanLen;i++)
			{
				Pan="0"+Pan;
			}
			//得到Pin格式
			byte[] tempPin = XORContent(res, hexStringToByte(Pan));
			DesPin = byte2hex(tempPin);
			if (DesPin.contains("F")){
				DesPin = DesPin.substring(2, DesPin.indexOf("F"));
			}else{
				DesPin = DesPin.substring(2);
			}
		}catch (Exception e){
			e.printStackTrace();
		}
		return DesPin;
	}
	/**
	 * EBC MAC算法
	 *
	 * @param MacKey
	 * 			明文MAC密钥
	 * @param macBlock
	 * 			加密数据
	 * @param MasterKey
	 * 			主密钥
	 */
	public static String MakeECBMac(String MacKey,String macBlock,String MasterKey)
	{
		log.debug("主密钥:"+MasterKey);
		log.debug("密文MAC:"+MacKey);
		if(null != MasterKey)
			MacKey=DesUtil.decode3DES(MacKey,MasterKey);
		log.debug("明文MAC:"+MacKey);
		String mac="";
		try{
			ByteBuffer buffer = ByteBuffer.allocate(2048);
			log.debug("原始数据=["+macBlock+"]");
			byte [] message=hexStringToByte(macBlock);
	
			buffer.put(message);
			//若原始数据不是8的倍数，则右补齐0x00
			if(buffer.position()%8!=0){
				int j=buffer.remaining()%8;
				for(int k=0;k<j;k++){
					buffer.put((byte) 0x00);
				}
			}
			buffer.flip();
			message=new byte[buffer.remaining()];
			buffer.get(message,0,message.length);
			buffer.flip();
			log.debug("补齐后的数据=["+byte2hex(message)+"]");
	
			byte [] tmp=new byte[8];
			byte [] str_init={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
			for(int i=0;i<buffer.limit()/8;i++){
				buffer.get(tmp);
				byte[] res=XORContent(str_init,tmp);
				log.debug("=====第"+(i+1)+"次异或开始========");
				log.debug("异或数据=["+byte2hex(str_init)+"]["+byte2hex(tmp)+"]");
				log.debug("异或的结果=["+byte2hex(res)+"]");
				str_init=res;
				log.debug("=====第"+(i+1)+"次异或结束========");
				log.debug("");
			}
			String ASC=HexStr2ASCII(byte2hex(str_init));
			log.debug("=====转换ASC开始========");
			log.debug("转换为16个字节的ASC码=["+byte2hex(str_init)+"]");
			log.debug("转换为ASC码的结果=["+ASC+"]");
			log.debug("=====转换ASC结束========");
			log.debug("");
			log.debug("=====取前8个字节做DES加密开始========");
			String ASCq8=ASC.substring(0, 16);
			byte[] res1=DesUtil.compute3DES(getDESKey(MacKey),hexStringToByte(ASCq8));
			
			log.debug("加密数据=["+ASCq8+"]["+MacKey+"]");
			log.debug("加密的结果=["+byte2hex(res1)+"]");
			log.debug("=====加密结束========");
			log.debug("=====ASC前8个字节密文与ASC后8字节异或开始========");
			String ASCh8=ASC.substring(16);
			log.debug("异或数据=["+byte2hex(res1)+"]["+ASCh8+"]");
			byte[] res2=XORContent(res1,hexStringToByte(ASCh8));
			log.debug("异或的结果=["+byte2hex(res2)+"]");
			log.debug("=====异或结束========");
			log.debug("=====异或结果DES加密开始========");
			byte[] res3=DesUtil.compute3DES(getDESKey(MacKey),res2);

			log.debug("加密数据=["+byte2hex(res2)+"]["+MacKey+"]");
			log.debug("加密的结果=["+byte2hex(res3)+"]");
			log.debug("=====加密结束========");
			String ASC2=HexStr2ASCII(byte2hex(res3));
			log.debug("=====转换ASC开始========");
			log.debug("转换为16个字节的ASC码=["+byte2hex(res3)+"]");
			log.debug("转换为ASC码的结果=["+ASC2+"]");
			log.debug("=====转换ASC结束========");
			mac=ASC2.substring(0,16);
			log.debug("UBC运算结果=["+mac+"]");
		}catch (Exception e) {
			e.printStackTrace();
		}
		return mac;
	}


	/**
	 * 中岚 ECB MAC算法
	 *
	 * @param MacKey
	 * 			明文MAC密钥
	 * @param macBlock
	 * 			加密数据
	 * @param MasterKey
	 * 			主密钥
	 */
	public static String MakeZhongLanECBMac(String MacKey,String macBlock,String MasterKey) {
		System.out.println("主密钥:"+MasterKey);
		System.out.println("密文MAC:"+MacKey);
		if(null != MasterKey)
			MacKey=DesUtil.decode3DES(MacKey,MasterKey);
		System.out.println("明文MAC:"+MacKey);
		String mac="";
		try{
			byte[] message = hexStringToByte(macBlock);
			mac = clacMac(hexStringToByte(MacKey),message);
			System.out.println("MAC: " + mac);
		}catch (Exception e) {
			e.printStackTrace();
		}
		return mac;
	}
	/**
	 * 中岚 ECB MAC算法
	 *
	 * @param MacKey
	 * 			明文MAC密钥
	 * @param macBlock
	 * 			加密数据
	 * @param MasterKey
	 * 			主密钥
	 */
	public static String MakeKaYinKaECBMac(String MacKey,String macBlock,String MasterKey) {
		System.out.println("主密钥:"+MasterKey);
		System.out.println("密文MAC:"+MacKey);
		if(null != MasterKey){
			MacKey = DesUtil.decodc(MacKey, MasterKey);
		}
		System.out.println("明文MAC:"+MacKey);
		String mac="";
		try{
			byte[] message = hexStringToByte(macBlock);
			mac = clacKaYinKaMac(hexStringToByte(MacKey),message);
			System.out.println("MAC: " + mac);
		}catch (Exception e) {
			e.printStackTrace();
		}
		return mac;
	}
	//异或
	public static byte[] XORContent( byte[] content1,byte[] content2 )
	{
	   int i=0;
	   int len = content1.length;
	   //byte []sOutMAC =new byte[8];
	   byte[] res=new byte[len];
	   for( i=0; i<len; i++){
		   res[i]=(byte) (content1[i]^content2[i]);
	   }
	   return res;
	   
	}
	//DES加密
	public static byte[] encodc(byte[] myinfo,byte[] key) {
		// Security.addProvider(new com.sun.crypto.provider.SunJCE());
		String Algorithm = "DES"; //DES,DESede,Blowfish
		try {
			DESKeySpec dks = new DESKeySpec(key);

			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(Algorithm);
			SecretKey deskey = keyFactory.generateSecret(dks);
			//log.debug("加密前数据=[" + byte2hex(myinfo)+"]");
			Cipher c1 = Cipher.getInstance("DES/ECB/NoPadding");
			//Cipher c1 = Cipher.getInstance("DES");
			c1.init(Cipher.ENCRYPT_MODE, deskey);
			byte[] cipherByte = c1.doFinal(myinfo);
			//log.debug("加密结果=[" + byte2hex(cipherByte)+"]");
			return cipherByte;

		} catch (Exception e1) {
			e1.printStackTrace();
		}
		return null;
	}
	//DES解密
	public static byte[] decodc(byte[] myinfo,byte[] key) {
		String Algorithm = "DES"; //DES,DESede,Blowfish
		try {
			DESKeySpec dks = new DESKeySpec(key);

			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(Algorithm);
			SecretKey deskey = keyFactory.generateSecret(dks);

			log.debug("解密前数据=[" + byte2hex(myinfo)+"]");

			Cipher c1 = Cipher.getInstance("DES/ECB/NoPadding");
			c1.init(Cipher.DECRYPT_MODE, deskey);

			byte[] cipherByte = c1.doFinal(myinfo);
			log.debug("解密结果=[" + byte2hex(cipherByte)+"]");
			return cipherByte;

		} catch (Exception e1) {
			e1.printStackTrace();
		}
		return null;
	}
	//DES加密
	public static byte[] encodc2(byte[] myinfo,byte[] key) {
		// Security.addProvider(new com.sun.crypto.provider.SunJCE());
		String Algorithm = "DESede"; //DES,DESede,Blowfish
		try {
			DESKeySpec dks = new DESKeySpec(key);

			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(Algorithm);
			SecretKey deskey = keyFactory.generateSecret(dks);
			//log.debug("加密前数据=[" + byte2hex(myinfo)+"]");
			Cipher c1 = Cipher.getInstance("DESede/ECB/NoPadding");
			//Cipher c1 = Cipher.getInstance("DES");
			c1.init(Cipher.ENCRYPT_MODE, deskey);
			byte[] cipherByte = c1.doFinal(myinfo);
			//log.debug("加密结果=[" + byte2hex(cipherByte)+"]");
			return cipherByte;

		} catch (Exception e1) {
			e1.printStackTrace();
		}
		return null;
	}
	public static String byte2hex(byte[] b) {
		String hs = "";
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1)
				hs = hs + "0" + stmp;
			else
				hs = hs + stmp;
		}
		return hs.toUpperCase();
	}
	public static byte[] getDESKey(String hexKey){
		String strKey=hexKey.toUpperCase();
		return hexStringToByte(strKey);
	}
	public static byte[] hexStringToByte(String hex) {
		hex=hex.toUpperCase();
		int len = (hex.length() / 2);
		byte[] result = new byte[len];
		char[] achar = hex.toCharArray();
		for (int i = 0; i < len; i++) {
			int pos = i * 2;
			result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
		}
		return result;
	}
	private static byte toByte(char c) {
		byte b = (byte) "0123456789ABCDEF".indexOf(c);
		return b;
	}
	public static String Int2HexStr(int n)
	{
		String HexStr=Integer.toHexString(n);
		HexStr=HexStr.length()==1?"0"+HexStr:HexStr;
		return HexStr;
	}
	//将字符串转为ASCII码
	public static String HexStr2ASCII(String cnStr)
	{
		StringBuffer strBuf=new StringBuffer();
		//将字符串转换成字节序列
		byte[] bGBK=cnStr.getBytes();
		for(int i=0;i<bGBK.length;i++)
		{
			//将每个字符转换成ASCII码
			strBuf.append(Integer.toHexString(bGBK[i] & 0xff));
			//log.debug(Integer.toHexString(bGBK[i] & 0xff)); 
		}
		return strBuf.toString();
	}

    /**
     * ANSI 9.9 MAC算法
     *
     * @param MacKey
     * 			明文MAC密钥
     * @param macBlock
     * 			加密数据
     */
    public static String MakeANSI99Mac(String MacKey,String macBlock,String MasterKey){
        log.debug("主密钥:"+MasterKey);
        log.debug("密文MAC:"+MacKey);
        if(null != MasterKey)
            MacKey=DesUtil.decode3DES(MacKey,MasterKey);
        log.debug("明文MAC:"+MacKey);
        String mac="";
        try{
            ByteBuffer buffer = ByteBuffer.allocate(2048);
            log.debug("原始数据=[" + macBlock + "]");
            byte [] message=hexStringToByte(macBlock);

            buffer.put(message);
            //若原始数据不是8的倍数，则右补齐0x00
            if(buffer.position()%8!=0){
                int j=buffer.remaining()%8;
                for(int k=0;k<j;k++){
                    buffer.put((byte) 0x00);
                }
            }
            buffer.flip();
            message=new byte[buffer.remaining()];
            buffer.get(message,0,message.length);
            buffer.flip();
            log.debug("补齐后的数据=["+byte2hex(message)+"]");

            byte [] tmp=new byte[8];
            byte [] str_init={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
            for(int i=0;i<buffer.limit()/8;i++){
                buffer.get(tmp);
                byte[] res=XORContent(str_init,tmp);
                log.debug("=====第"+(i+1)+"次异或开始========");
                log.debug("异或数据=["+byte2hex(str_init)+"]["+byte2hex(tmp)+"]");
                log.debug("异或的结果=["+byte2hex(res)+"]");
//				byte[] res1=DesUtil.encrypt(res, MacKey.substring(0, 16).getBytes("UTF-8"));
                byte[] res1=DesUtil.compute3DES(getDESKey(MacKey),res);
                log.debug("加密的结果=["+byte2hex(res1)+"]");
                str_init=res1;
                log.debug("=====第"+(i+1)+"次异或结束========");
                log.debug("");
            }

            //byte[] res1=DesUtil.compute3DES(getDESKey(MacKey),str_init);
            mac=byte2hex(str_init);

            log.debug("mac运算结果=["+mac+"]");
        }catch (Exception e) {
            e.printStackTrace();
        }
        return mac;
    }
	/**
	 * ANSI 9.19 MAC算法
	 *
	 * @param MacKey
	 * 			明文MAC密钥
	 * @param macBlock
	 * 			加密数据
	 */
	public static String MakeANSI919Mac(String MacKey,String macBlock,String MasterKey){
		log.debug("主密钥:"+MasterKey);
		log.debug("密文MAC:"+MacKey);
		if(null != MasterKey)
			MacKey=DesUtil.decode3DES(MacKey,MasterKey);
		log.debug("明文MAC:" + MacKey);
		String mac="";
		try{
			log.debug("原始数据=["+macBlock+"]");
			//mackey
			byte[] MAC_KEY = hexStringToByte(MacKey);
			//对数据进行补0操作
			int length = macBlock.length()%16;
			if (macBlock.length()%16 != 0){
				for (int i = 0; i < 16-length; i++){
					macBlock += "0";
				}
			}
			byte [] mab=hexStringToByte(macBlock);
			log.debug("补齐后的数据=["+byte2hex(mab)+"]");
			int mabLength = mab.length%8==0 ? mab.length : mab.length+(8-mab.length%8);
			byte[] mabByte = new byte[mabLength];
			System.arraycopy(mab, 0, mabByte, 0, mabLength);
			byte[] macKeyFirst = new byte[8];
			System.arraycopy(MAC_KEY, 0, macKeyFirst, 0, 8);
			byte[] macKeyEnd = new byte[8];
			System.arraycopy(MAC_KEY, 8, macKeyEnd, 0 ,8);
			//获取秘钥的前半部和后半部
			byte[] first8 = new byte[8];
			System.arraycopy(mabByte, 0, first8, 0, 8);
			first8 = encrypt(first8, macKeyFirst);
			for (int i = 1; i < mabByte.length/8; i++){
				byte[] temp = new byte[8];
				System.arraycopy(mabByte,i*8,temp,0,8);
				first8 = XORContent(first8, temp);
				first8 = encrypt(first8, macKeyFirst);
			}
			//将最终结果与MaC的右半部解密
			first8 = decrypt(first8, macKeyEnd);
			//将解密结果与MAC秘钥左半部进行加密
			first8 = encrypt(first8, macKeyFirst);
			byte[] macByte = byte2hex(first8).substring(0,8).getBytes();
			mac = byte2hex(macByte);
			log.debug("mac运算结果=["+mac+"]");
		}catch (Exception e) {
			e.printStackTrace();
		}
		return mac;
	}
	/**
	 * Des加密算法
	 * @param src 数据源
	 * @param key 密钥，长度必须是8的倍数
	 * @return
	 * @throws Exception
	 */
	public static byte[] encrypt(byte[] src, byte[] key) throws Exception {
		// DES算法要求有一个可信任的随机数源
		SecureRandom sr = new SecureRandom();

		// 从原始密匙数据创建DESKeySpec对象
		DESKeySpec dks = new DESKeySpec(key);

		// 创建一个密匙工厂，然后用它把DESKeySpec转换成一个SecretKey对象
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
		SecretKey securekey = keyFactory.generateSecret(dks);

		// Cipher对象实际完成加密操作
		Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

		// 用密匙初始化Cipher对象
		cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);

		// 执行加密操作
		return cipher.doFinal(src);
	}
	/**
	 *
	 * @param src 数据源
	 * @param key 密钥，长度必须是8的倍数
	 * @return
	 * @throws Exception
	 */
	public static byte[] decrypt(byte[] src, byte[] key) throws Exception {
		// DES算法要求有一个可信任的随机数源
		SecureRandom sr = new SecureRandom();
		// 从原始密匙数据创建一个DESKeySpec对象
		DESKeySpec dks = new DESKeySpec(key);
		// 创建一个密匙工厂，然后用它把DESKeySpec对象转换成一个SecretKey对象
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
		SecretKey securekey = keyFactory.generateSecret(dks);
		// Cipher对象实际完成解密操作
		Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
		// 用密匙初始化Cipher对象
		cipher.init(Cipher.DECRYPT_MODE, securekey, sr);

		// 正式执行解密操作
		return cipher.doFinal(src);
	}
    /**
     * EBC MAC算法
     *
     * @param MacKey
     * 			明文MAC密钥
     * @param macBlock
     * 			加密数据
     * @param MasterKey
     * 			主密钥
     */
    public static String MakePOSPMac(String MacKey,String macBlock,String MasterKey)
    {
        log.debug("主密钥:"+MasterKey);
        log.debug("密文MAC:"+MacKey);
        if(null != MacKey) MacKey=DesUtil.decode3DES(MacKey,MasterKey);
        log.debug("明文MAC:"+MacKey);
        String mac="";
        try{
            ByteBuffer buffer = ByteBuffer.allocate(2048);
            log.debug("原始数据=["+macBlock+"]");
            byte [] message=hexStringToByte(macBlock);

            buffer.put(message);
            //若原始数据不是8的倍数，则右补齐0x00
            if(buffer.position()%8!=0){
                int j=buffer.remaining()%8;
                for(int k=0;k<j;k++){
                    buffer.put((byte) 0x00);
                }
            }
            buffer.flip();
            message=new byte[buffer.remaining()];
            buffer.get(message,0,message.length);
            buffer.flip();
            log.debug("补齐后的数据=["+byte2hex(message)+"]");

            byte [] tmp=new byte[8];
            byte [] str_init={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
            for(int i=0;i<buffer.limit()/8;i++){
                buffer.get(tmp);
                byte[] res=XORContent(str_init,tmp);
                log.debug("=====第"+(i+1)+"次异或开始========");
                log.debug("异或数据=["+byte2hex(str_init)+"]["+byte2hex(tmp)+"]");
                log.debug("异或的结果=["+byte2hex(res)+"]");
                str_init=res;
                log.debug("=====第"+(i+1)+"次异或结束========");
                log.debug("");
            }
            String ASC=HexStr2ASCII(byte2hex(str_init));
            log.debug("=====转换ASC开始========");
            log.debug("转换为16个字节的ASC码=["+byte2hex(str_init)+"]");
            log.debug("转换为ASC码的结果=["+ASC+"]");
            log.debug("=====转换ASC结束========");
            log.debug("");
            log.debug("=====取前8个字节做DES加密开始========");
            String ASCq8=ASC.substring(0, 16);
            byte[] res1=DesUtil.compute3DES(getDESKey(MacKey),hexStringToByte(ASCq8));

            log.debug("加密数据=["+ASCq8+"]["+MacKey+"]");
            log.debug("加密的结果=["+byte2hex(res1)+"]");
            log.debug("=====加密结束========");
            log.debug("=====ASC前8个字节密文与ASC后8字节异或开始========");
            String ASCh8=ASC.substring(16);
            log.debug("异或数据=["+byte2hex(res1)+"]["+ASCh8+"]");
            byte[] res2=XORContent(res1,hexStringToByte(ASCh8));
            log.debug("异或的结果=["+byte2hex(res2)+"]");
            log.debug("=====异或结束========");
            log.debug("=====异或结果DES加密开始========");
            byte[] res3=DesUtil.compute3DES(getDESKey(MacKey),res2);

            log.debug("加密数据=["+byte2hex(res2)+"]["+MacKey+"]");
            log.debug("加密的结果=["+byte2hex(res3)+"]");
            log.debug("=====加密结束========");
            String ASC2=HexStr2ASCII(byte2hex(res3));
            log.debug("=====转换ASC开始========");
            log.debug("转换为16个字节的ASC码=["+byte2hex(res3)+"]");
            log.debug("转换为ASC码的结果=["+ASC2+"]");
            log.debug("=====转换ASC结束========");
            mac=ASC2.substring(0,16);
            log.debug("UBC运算结果=["+mac+"]");
        }catch (Exception e) {
            e.printStackTrace();
        }
        return mac;
    }
	/**
	 * pin加密 不带主账号信息
	 * @param Pin 主账号
	 * @param Pin 明文密码
	 * @param PinKey 明文PIN密钥
	 * @param MasterKey 主密钥
	 */
	public static String PosEncryptPin(String bit53,String Pin,String PinKey, String MasterKey,Date date){
		if(null != MasterKey)
			PinKey=DesUtil.decode3DES(PinKey,MasterKey);
		String DesPin="";
		try{//Pin格式
			Pin=Int2HexStr(Pin.length())+Pin;
			int PinLen=Pin.length();
			for(int j=0;j<16-PinLen;j++)
			{
				Pin+="F";
			}
			//生成新的pinKey
			String nowTime = TimeUtils.getDateTime(date,"yyyyMM");
			String temp = bit53.substring(0, 8);//获取53域前8位
			String newPin = nowTime + temp + "80";//生成变种key
			//newPin = "2015080714065380";
			//做3DES加密
			byte[] newKey = DesUtil.compute3DES(hexStringToByte(PinKey),hexStringToByte(newPin));
//			log.debug("变种秘钥=["+byte2hex(newKey)+"     "+"22A57CA3E8842D63".equals(byte2hex(newKey))+"]");
			//将pin格式转换为字节数组
			byte[] pinByte = hexStringToByte(Pin);
			//新的pinKey对pin格式的数据进行单des加密
			byte[] res = encodc(pinByte, newKey);
			DesPin = byte2hex(res);
//			log.debug("密码=["+DesPin+"     "+"9AED59306EDBEEC7".equals(DesPin)+"]");
		}catch (Exception e) {
			e.printStackTrace();
		}
		return DesPin;
	}

	/**
	 * 大POS磁道信息加密
	 * @param trkKey
	 * @param track
	 * @return
	 */
	public static String PosEncryptTrack(String bit53, String trkKey,String MasterKey,String track,Date date) throws Exception {
		System.out.println("***********bit53="+bit53);
		if(null != MasterKey)
			trkKey=DesUtil.decode3DES(trkKey,MasterKey);

		//生成新的pinKey
		String nowTime = TimeUtils.getDateTime(date, "yyyyMM");
		String temp = bit53.substring(0, 8);//获取53域前8位
		String newPin = nowTime + temp + "80";//生成变种key

//		newPin = "2015080714065380";//###########3

		byte[] tempKey = DesUtil.compute3DES(hexStringToByte(trkKey), hexStringToByte(newPin));
		log.debug("变种秘钥=["+byte2hex(tempKey));//+"     "+"6A2985F6DB7C5ED2".equals(byte2hex(tempKey))+"]"
		//获取53域后8位
		String temp2 = bit53.substring(8).toUpperCase();
		System.out.println("***********temp2="+temp2);
		String dongtaiKey = HexStr2ASCII(temp2);
		System.out.println("***********dongtaiKey="+dongtaiKey);// + "   " +"3030303232323932".equals(dongtaiKey) );
		System.out.println("***********tempKey="+tempKey.length);
		byte [] geneKey = TestDes.encodc(hexStringToByte(dongtaiKey), tempKey);
		log.debug("新变种秘钥=["+byte2hex(geneKey));//+"     "+"08CDDD2DDB485C5E".equals(byte2hex(geneKey))+"]");

		//将磁道数据按8位分组用磁道密钥加密，不足8位的无需加密。
		StringBuilder sb = new StringBuilder("");
		int count = track.length() / 16;
		String DN1 = "";
		byte[] bytes;
		if (track.length()%16 != 0){
			DN1 = track.substring(count*16);
		}
		String tem = "";
		for (int i=0; i<count; i++){
			String strTrack = track.substring(i * 16, (i + 1) * 16);
			bytes = TestDes.encodc(hexStringToByte(strTrack),geneKey);
			tem = byte2hex(bytes);
			sb.append(tem);
		}
		String miTrk = sb.toString() + DN1;
		log.debug("新变种秘钥=["+miTrk+"     ");//+"713E5833DC03C38F2F5FC4D85D2E6A1220000".equals(miTrk)+"]");
		return miTrk;
	}

	/**
	 * 大pos MAC算法
	 *
	 * @param MacKey
	 * 			明文MAC密钥
	 * @param macBlock
	 * 			加密数据
	 * @param MasterKey
	 * 			主密钥
	 */
	public static String encryptPOSMac(String bit53, String MacKey,String macBlock,String MasterKey,Date date){
		log.debug("主密钥:"+MasterKey);
		log.debug("密文MAC:"+MacKey);
		if(null != MasterKey)
			MacKey=DesUtil.decode3DES(MacKey,MasterKey);
		log.debug("明文MAC:" + MacKey);
		String mac="";
		try{
			//生成新的macKey
			String nowTime = TimeUtils.getDateTime(date,"yyyyMM");
			String temp = bit53.substring(0, 8);//获取53域前8位时间
			String newMac = nowTime + temp + "80";

//			newMac = "2015110714065380";//##########

			byte[] newMacs = DesUtil.compute3DES(hexStringToByte(MacKey),hexStringToByte(newMac));
			log.debug("变种秘钥=["+byte2hex(newMacs));//+"  "+"E7C33EF188E5A750".equals(byte2hex(newMacs))+"]");

			ByteBuffer buffer = ByteBuffer.allocate(2048);
			log.debug("原始数据=["+macBlock+"]");
			macBlock += "80";
			if(macBlock.length() % 2 == 1)macBlock += "0";
			while(macBlock.length() % 16 != 0){
				macBlock += "00";
			}
//			macBlock += "8000000000000000";
			byte [] message=hexStringToByte(macBlock);
			log.debug("message 长度=["+message.length+"]");
			buffer.put(message);
			buffer.flip();
			log.debug("补齐后的数据=["+byte2hex(message)+"]");

			byte [] tmp=new byte[8];
			byte [] str_init={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
			byte [] str_end={(byte) 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
			for(int i=0;i<buffer.limit()/8;i++){
				buffer.get(tmp);
				byte[] res=XORContent(str_init,tmp);
//				log.debug("=====第"+(i+1)+"次异或开始========");
				log.debug("异或数据=["+byte2hex(str_init)+"]["+byte2hex(tmp)+"]");
				log.debug("异或的结果=["+byte2hex(res)+"]");
				//使用变种macKey对数据进行单des加密
				byte[] res1=encodc(res, newMacs);
				log.debug("异或并加密结果=["+byte2hex(res1)+"]");
				str_init = res1;
//				log.debug("=====第"+(i+1)+"次异或结束========");
			}
			//最终的加密结果与0x8000000000000000异或，异或与Mac置换密钥加密，加密结果转16进制字符串，然后取前8位
			byte[] res=XORContent(str_init,str_end);
			log.debug("异或数据=["+byte2hex(str_init)+"]["+byte2hex(str_end)+"]");
			log.debug("异或的结果=["+byte2hex(res)+"]");
			str_init=encodc(res, newMacs);

			String ASC=byte2hex(str_init);
			log.debug("MAC运算结果=["+ASC+"]");
			mac = byte2hex(ASC.substring(0,8).getBytes());
			log.debug("MAC运算结果=["+mac+ "   ");//+ "DC091A23".equals(mac)+"]");
		}catch (Exception e) {
			e.printStackTrace();
		}
		return mac;
	}

	/**
	 * 对特殊域加密 2域,61域,62域
	 * @param bit53
	 * @param area
	 * @param sensKey
	 * @return
	 */
	public static String encryptSpecial(String bit53, String area, String sensKey, Date date) throws Exception {
		//取53域的前8位
		String nowTime = TimeUtils.getDateTime(date, "yyyyMM");;//得到交易时间
		String temp = bit53.substring(0, 8);//获取53域前8位
		String newPin = nowTime + temp + "80";

		//newPin = "2015102321182380";

		String length = NumberUtil.supplyAll(String.valueOf(area.length()), 4);
		String P = HexStr2ASCII(area);
		String D = length + P;
		while(D.length()%16 != 0 ){
			D += "0";
		}

		log.debug("敏感数据秘钥=["+D+"]    ");//+"9CE138B5CF7CCC01".equals(D));

		//生成变种key
		byte[] geneKey = DesUtil.compute3DES(hexStringToByte(sensKey),hexStringToByte(newPin));
		log.debug("敏感数据变种秘钥=["+byte2hex(geneKey)+"]    ");//+"9CE138B5CF7CCC01".equals(byte2hex(geneKey)));

		ByteBuffer buffer = ByteBuffer.allocate(2048);
		byte [] message=hexStringToByte(D);
		log.debug("敏感基础数据 长度=["+message.length+"]");
		buffer.put(message);
		buffer.flip();
		byte [] tmp=new byte[8];
		StringBuilder sb = new StringBuilder();
		byte [] str_init=null;
		for(int i=0;i<buffer.limit()/8;i++){
			buffer.get(tmp);
			str_init=encodc(tmp, geneKey);
			log.debug("敏感域加密数据=["+byte2hex(tmp)+"]  ["+byte2hex(str_init)+"]");
			sb.append(byte2hex(str_init));
		}

		String sex = sb.toString();//byte2hex(geneKey);
		log.debug("sex=["+sex+"]");
		return sex;
	}
	
	public static byte byteXOR(byte src, byte src1) {
		return (byte) ((src & 0xFF) ^ (src1 & 0xFF));
	}

	public static byte[] bytesXOR(byte[] src, byte[] src1) {
		int length = src.length;
		if (length != src1.length) {
			return null;
		}
		byte[] result = new byte[length];
		for (int i = 0; i < length; i++) {
			result[i] = byteXOR(src[i], src1[i]);
		}
		return result;
	}

	/**
	 * mac计算,数据不为8的倍数，需要补0，将数据8个字节进行异或，再将异或的结果与下一个8个字节异或，一直到最后，将异或后的数据进行DES计算
	 * @param key
	 * @param Input
	 * @return
	 */
	public static String clacMac(byte[] key, byte[] Input) {
		int length = Input.length;
		int x = length % 8;
		int addLen = 0;
		if (x != 0) {
			addLen = 8 - length % 8;
		}
		int pos = 0;
		byte[] data = new byte[length + addLen];
		System.arraycopy(Input, 0, data, 0, length);
		byte[] oper1 = new byte[8];
		System.arraycopy(data, pos, oper1, 0, 8);
		pos += 8;
		for (int i = 1; i < data.length / 8; i++) {
			byte[] oper2 = new byte[8];
			System.arraycopy(data, pos, oper2, 0, 8);
			byte[] t = bytesXOR(oper1, oper2);
			oper1 = t;
			pos += 8;
		}
		// 将异或运算后的最后8个字节（RESULT BLOCK）转换成16个HEXDECIMAL：
		byte[] resultBlock = bytesToHexString(oper1).getBytes();
		// 取前8个字节用mkey1，DES加密
		byte[] front8 = new byte[8];
		System.arraycopy(resultBlock, 0, front8, 0, 8);
		byte[] behind8 = new byte[8];
		System.arraycopy(resultBlock, 8, behind8, 0, 8);
		byte[] desfront8 = DesUtil.encryptDes(front8, key);
		// 将加密后的结果与后8 个字节异或：
		byte[] resultXOR = bytesXOR(desfront8, behind8);
		// 用异或的结果TEMP BLOCK 再进行一次单倍长密钥算法运算
		byte[] buff = DesUtil.encryptDes(resultXOR, key);
		// 将运算后的结果（ENC BLOCK2）转换成16 个HEXDECIMAL asc
		// 取8个长度字节
		byte[] retBuf = new byte[8];
		System.arraycopy(bytesToHexString(buff).getBytes(), 0, retBuf, 0, 8);
		String mac = bytesToHexString(retBuf);
		return mac;
	}

	/**
	 * mac计算,数据不为8的倍数，需要补0，将数据8个字节进行异或，再将异或的结果与下一个8个字节异或，一直到最后，将异或后的数据进行DES计算
	 * @param key
	 * @param Input
	 * @return
	 */
	public static String clacKaYinKaMac(byte[] key, byte[] Input) {
		int length = Input.length;
		int x = length % 8;
		int addLen = 0;
		if (x != 0) {
			addLen = 8 - length % 8;
		}
		int pos = 0;
		byte[] data = new byte[length + addLen];
		System.arraycopy(Input, 0, data, 0, length);
		byte[] oper1 = new byte[8];
		System.arraycopy(data, pos, oper1, 0, 8);
		pos += 8;
		for (int i = 1; i < data.length / 8; i++) {
			byte[] oper2 = new byte[8];
			System.arraycopy(data, pos, oper2, 0, 8);
			byte[] t = bytesXOR(oper1, oper2);
			oper1 = t;
			pos += 8;
		}
		// 将异或运算后的最后8个字节（RESULT BLOCK）转换成16个HEXDECIMAL：
		byte[] resultBlock = bytesToHexString(oper1).getBytes();
		// 取前8个字节用mkey1，DES加密
		byte[] front8 = new byte[8];
		System.arraycopy(resultBlock, 0, front8, 0, 8);
		byte[] behind8 = new byte[8];
		System.arraycopy(resultBlock, 8, behind8, 0, 8);
		byte[] desfront8 = DesUtil.encryptDes(front8, key);
		// 将加密后的结果与后8 个字节异或：
		byte[] resultXOR = bytesXOR(desfront8, behind8);
		// 用异或的结果TEMP BLOCK 再进行一次单倍长密钥算法运算
		byte[] buff = DesUtil.encryptDes(resultXOR, key);
		// 将运算后的结果（ENC BLOCK2）转换成16 个HEXDECIMAL asc
		// 取8个长度字节
		byte[] retBuf = new byte[8];
		String mac = bytesToHexString(buff).substring(0,8);
//		System.arraycopy(bytesToHexString(buff).getBytes(), 0, retBuf, 0, 8);
//		String mac = bytesToHexString(retBuf);
		return mac;
	}

	public static final String bytesToHexString(byte[] bArray) {
		StringBuffer sb = new StringBuffer(bArray.length);
		String sTemp;
		for (int i = 0; i < bArray.length; i++) {
			sTemp = Integer.toHexString(0xFF & bArray[i]);
			if (sTemp.length() < 2)
				sb.append(0);
			sb.append(sTemp.toUpperCase());
		}
		return sb.toString();
	}


}